package cn.itsource.hrm.service.impl;

import cn.itsource.hrm.domain.Course;
import cn.itsource.hrm.domain.CourseDetail;
import cn.itsource.hrm.domain.CourseMarket;
import cn.itsource.hrm.domain.CourseResource;
import cn.itsource.hrm.es.doc.EsCourse;
import cn.itsource.hrm.es.repository.EsCourseRepository;
import cn.itsource.hrm.mapper.*;
import cn.itsource.hrm.query.CourseQuery;
import cn.itsource.hrm.service.ICourseService;
import cn.itsource.hrm.util.PageList;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yhptest
 * @since 2020-06-26
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseResourceMapper courseResourceMapper;

    @Autowired
    private EsCourseRepository repository;

    /**
     * 上线： 在es添加数据，修改数据库的状态和上架时间
     * 下线： 在es删除数据，修改数据库状态和下架时间
     * @param ids
     * @param flag
     */

    @Override
    public void onlineOrOffLine(List<Long> ids, int flag) {
        if (flag==0){
            //上线
            //1 添加索引库
            List<EsCourse> esCourses = getEsCourses(ids);
            repository.saveAll(esCourses);
            //2 修改数据库 update t_course set status=1 and onlineTime=#{onlineTime} where id in (1,2,3)
            Map<String,Object> params = new HashMap<>();
            params.put("onLineTime",new Date());
            params.put("ids",ids);
            courseMapper.onLine(params);
        }else{
            //下线
            //1删除索引库
            for (Long id : ids) {
                repository.deleteById(id);
            }
            //2 修改数据库状态和下架时间  update t_course set status=0 and ooflineTime=#{onlineTime} where id in (1,2,3)
            Map<String,Object> params = new HashMap<>();
            params.put("offLineTime",new Date());
            params.put("ids",ids);
            courseMapper.offLine(params);
        }

    }

    @Override
    public PageList<EsCourse> queryCourseEs(CourseQuery query) {
        return dsl(query);
    }

    private PageList<EsCourse> dsl(CourseQuery query) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        /**
         *    keyword
         *     private Long courseType;
         *     private Long tenantId;
         *     private Float priceMin;
         *     private Float priceMax;
         *
         */
        //1 查询+过滤
        BoolQueryBuilder bool = QueryBuilders.boolQuery(); //query bool
        if (StringUtils.hasLength(query.getKeyword())){
            bool.must(QueryBuilders.matchQuery("all",query.getKeyword())); //query bool must match
        }
        if (query.getCourseType()!=null){

            bool.filter(QueryBuilders.matchQuery("courseTypeId",query.getCourseType()));//query bool filter
        }
        if (query.getTenantId()!=null){

            bool.filter(QueryBuilders.matchQuery("tenantId",query.getTenantId()));//query bool filter
        }
        if (query.getPriceMax()!=null && query.getPriceMin()!=null){
            bool.filter(QueryBuilders.rangeQuery("price").gte(query.getPriceMin()).lte(query.getPriceMax()));//query bool filter
        }
        builder.withQuery(bool);
        //2 排序

        if (StringUtils.hasLength(query.getSortType()) && StringUtils.hasLength(query.getSortMethod())){
            SortOrder defaluSortOrder = SortOrder.DESC;
            if (query.getSortMethod().equals("ASC")){
                defaluSortOrder = SortOrder.ASC;
            }
            if (query.getSortType().equals("jg")){

                builder.withSort(SortBuilders.fieldSort("price").order(defaluSortOrder));//通过age倒序排列
            }
            if (query.getSortType().equals("xp")){

                builder.withSort(SortBuilders.fieldSort("startTime").order(defaluSortOrder));//通过age倒序排列
            }
            //.....
        }
        //3 分页
        builder.withPageable(PageRequest.of(query.getPage()-1,query.getRows()));//当前页，每页显示多少个。
        //4 截取字段
//        builder.withSourceFilter(new FetchSourceFilter(new String[]{"name","age","id"},
//                null));
        //5 获取
        Page<EsCourse> page = repository.search(builder.build());
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("总数:"+page.getTotalElements());
        return new PageList<>(page.getTotalElements(),page.getContent());
    }

    /**
     * 申明
     * 转换
     * 返回
     * @param ids
     * @return
     */
    private List<EsCourse> getEsCourses(List<Long> ids) {
        List<EsCourse> result = new ArrayList<>();//申明
        //转换
        List<Course> courses = courseMapper.selectBatchIds(ids);
        for (Course course : courses) {
            result.add(course2esCourse(course));
        }
        //返回
        return result;
    }

    @Autowired
    private CourseTypeMapper courseTypeMapper;
    private EsCourse course2esCourse(Course course) {

        EsCourse result = new EsCourse();
        //  2 转换
        result.setId(course.getId());
        result.setName(course.getName());
        result.setUsers(course.getUsers());

        Long courseTypeId = course.getCourseTypeId();
        result.setCourseTypeId(courseTypeId);
        //type-同库-没有做关联查询
        if (courseTypeId != null) {
            String typeName = courseTypeMapper.selectById(courseTypeId).getName();
            result.setCourseTypeName(typeName);
        }
        result.setGradeId(course.getGrade());
        result.setGradeName(course.getGradeName());
        result.setStatus(course.getStatus());
        result.setTenantId(course.getTenantId());
        result.setTenantName(course.getTenantName());
        result.setUserId(course.getUserId());
        result.setUserName(course.getUserName());
        result.setStartTime(course.getOnlineTime());
        result.setEndTime(course.getOfflineTime());
        //Detail 查询是在all
        List<CourseDetail> courseDetails = courseDetailMapper.selectList(new EntityWrapper<CourseDetail>()
                .eq("course_id", course.getId()));
        if (courseDetails!=null && courseDetails.size()>0){
            result.setIntro(courseDetails.get(0).getIntro());
        }
        //resource
        List<CourseResource> courseResources = courseResourceMapper.selectList(new EntityWrapper<CourseResource>()
                .eq("course_id", course.getId()));
        if (courseResources!=null && courseResources.size()>0){
            result.setResources(courseResources.get(0).getResources());
        }
        //market
        List<CourseMarket> courseMarkets = courseMarketMapper.selectList(new EntityWrapper<CourseMarket>()
                .eq("course_id", course.getId()));
        if (courseMarkets!=null && courseMarkets.size()>0){
            CourseMarket courseMarket = courseMarkets.get(0);
            result.setExpires(courseMarket.getExpires());
            result.setPrice(new BigDecimal(courseMarket.getPrice()));
            result.setPriceOld(new BigDecimal(courseMarket.getPriceOld()));
            result.setQq(courseMarket.getQq());
        }
        return result;
    }



    @Override
    public boolean insert(Course entity) {
        //保存本身表
        /*
        private Long tenantId;
        private Long userId;*/
        Long userId = 42L;
        Long tenantId = 26L;
        entity.setUserId(userId);
        entity.setTenantId(tenantId);
        entity.setStatus(0);
        if (entity.getCourseResource()!=null)
            entity.setPic(entity.getCourseResource().getResources().split(",")[0]);
        courseMapper.insert(entity);
        //保存管理表 detail market resoruce
        if( entity.getCourseDetail()!=null){
            entity.getCourseDetail().setCourseId(entity.getId());
            courseDetailMapper.insert(entity.getCourseDetail());
        }
        if( entity.getCourseMarket()!=null){
            entity.getCourseMarket().setCourseId(entity.getId());
            courseMarketMapper.insert(entity.getCourseMarket());
        }
        if( entity.getCourseResource()!=null){
            entity.getCourseResource().setCourseId(entity.getId());
            courseResourceMapper.insert(entity.getCourseResource());
        }
        return true;
    }


    @Override
    public boolean deleteById(Serializable id) { //同步删除
        courseDetailMapper.delete(new EntityWrapper<CourseDetail>().eq("course_id",id));
        courseResourceMapper.delete(new EntityWrapper<CourseResource>().eq("course_id",id));
        courseMarketMapper.delete(new EntityWrapper<CourseMarket>().eq("course_id",id));
        Course course = courseMapper.selectById(id);
        if (course.getStatus()==1){
            repository.deleteById(course.getId());
        }
        courseMapper.deleteById(id);
        return true;
    }

    @Override
    public boolean updateById(Course entity) { //同步修改
        courseDetailMapper.updateById(entity.getCourseDetail());
        courseResourceMapper.updateById(entity.getCourseResource());
        courseMarketMapper.updateById(entity.getCourseMarket());
        courseMapper.updateById(entity);
        Course course = courseMapper.selectById(entity.getId());
        if (course.getStatus()==1){
            EsCourse esCourse = course2esCourse(course);
            esCourse.setId(course.getId()); //有id就可以修改
            repository.save(esCourse);
        }
        return true;
    }
}
